<?php
/**
 * This file (functions.php) is used only for the simple functions which have special meanings:
 * 1. auto-loading the classes files
 * 2. register different handlers (error handler, shutdown handler)
 * 3. shorting the call to some often used method from some class. Ex. conf() => Config::get(), t() => Translations::t()
 */

/**
 * Auto-loading / auto-including the files for all existing classes.
 * We should not use the conf() function inside __autoload because it loads the Config class itself.
 *
 * @param string $className
 * @return void
 */
function __autoload($className){

	$found = false;
	$parts = explode("_", $className);
	$classFilename = array_pop($parts);
	$parts = array_map('strtolower', $parts);

	/**
	 * In case the current auto-loaded class is the controller (page) class and it is located in a sub-folder
	 * of /page/be/ or /page/fe/, we're creating a constant which contains the alternative path for template files
	 * specific for this controller. Normally the loading of a controller should happen only once per script execution
	 * but in any case we're checking if the constant was not already defined.
	 */
	if (isset($parts[0]) && $parts[0] == 'page' && !defined('TEMPLATES_ALT_PATH') && ($foldersCount = count($parts)) > 2) {
		$templatesAltPath = '';
		for ($i = 2; $i < $foldersCount; $i++) {
			$templatesAltPath .= $parts[$i].DS;
		}
		define('TEMPLATES_ALT_PATH', $templatesAltPath);
	}


	// In case we have a simple class (not a controller or model) we search for it in "utils" folder
	$classPath = count($parts) > 0 ? implode(DS, $parts).DS : 'utils'.DS;
	$fullClassPath = $classPath.$classFilename.'.class.php';

	if (file_exists(PROJECT_CLASSES_PATH.$fullClassPath)) {
		require_once(PROJECT_CLASSES_PATH.$fullClassPath);
		$found = true;
	} else if (file_exists(COUNTRY_CLASSES_PATH.$fullClassPath)) {
		require_once(COUNTRY_CLASSES_PATH.$fullClassPath);
		$found = true;
	} else if (file_exists(CLASSES_PATH.$fullClassPath)) {
		require_once(CLASSES_PATH.$fullClassPath);
		$found = true;
	}

    if (!$found) {
		// Zeta components
		if (strpos($className, 'ezc', 0) === 0) {
			require_once 'classes/libs/ezc/Base/src/base.php';
			ezcBase::autoload($className);
		} else {
			switch ($className) {

				case 'PHPMailer':
					require_once(CLASSES_PATH.'libs'.DS.'phpmailer'.DS.'class.phpmailer.php');
					require_once(CLASSES_PATH.'libs'.DS.'phpmailer'.DS.'class.smtp.php');
					break;

				default:
					break;
			}
		}
	}
}


/**
 * @param string $postKey
 * @param string $type
 * @param bool $ignoreStripTags
 * @return array|bool|float|int|null|string
 */
function onBeforeShutdown() {
	if ((MySQL::$queriesTime > 1.5 || MySQL::$queriesNr > 500) && Engine::$LOG instanceof Log) {
		Engine::$LOG->path = conf('ERROR_LOGS_PATH');
		$http_host = (isset($_SERVER['HTTP_HOST'])) ? $_SERVER['PHP_SELF'] : '';
		$php_self = (isset($_SERVER['PHP_SELF'])) ? $_SERVER['PHP_SELF']: '';
		$script_filename = (isset($_SERVER['SCRIPT_FILENAME'])) ? $_SERVER['SCRIPT_FILENAME'] : '';
		$request_uri = (isset($_SERVER['REQUEST_URI'])) ? $_SERVER['REQUEST_URI'] : '';
		Engine::$LOG->write(
			$http_host."\n".
				$php_self."\n".
				$script_filename."\n".
				$request_uri."\n".
			   'Q time: '.MySQL::$queriesTime."\n".
			   'Q nr.: '.MySQL::$queriesNr,
			($http_host ? $http_host.'_' : '').
				($request_uri ? $request_uri : $php_self)
		);
	}
	$error = error_get_last();
	if($error != null) {
		errorHandler($error['type'], $error['message'], $error['file'], $error['line']);
	}
}


/**
 * PHP's errors handler. We return always true because we don't want PHP to handle the errors afterward.
 *
 * @param $errorNumber
 * @param $errorString
 * @param $errorFile
 * @param $errorLine
 * @return bool
 */
function errorHandler($errorNumber, $errorString, $errorFile, $errorLine) {
	if (conf('DEBUG') == true) {
		Engine::$TPL->assign('errorNumber', $errorNumber);
		Engine::$TPL->assign('errorString', $errorString);
		Engine::$TPL->assign('errorFile', $errorFile);
		Engine::$TPL->assign('errorLine', $errorLine);
		switch ($errorNumber) {
			case E_ERROR:
			case E_PARSE:
			case E_CORE_ERROR:
			case E_COMPILE_ERROR:
			case E_USER_ERROR:
			case E_RECOVERABLE_ERROR:
				$debugArray = debug_backtrace();
				$debugCounter = count($debugArray);
				$debugArray = array_reverse($debugArray);
				Engine::$TPL->assign('debugArray', $debugArray);
				Engine::$TPL->assign('debugCounter', $debugCounter);
				Engine::$TPL->display('error');
				exit;
			case E_WARNING:
			case E_CORE_WARNING:
			case E_COMPILE_WARNING:
			case E_USER_WARNING:
				Engine::$TPL->display('warning');
				break;
			default:
				Engine::$TPL->display('notice');
				break;
		}
	} else {
		if (Engine::$LOG instanceof Log) {
			Engine::$LOG->path = conf('ERROR_LOGS_PATH');
			switch ($errorNumber) {
				case E_ERROR:
				case E_PARSE:
				case E_CORE_ERROR:
				case E_COMPILE_ERROR:
				case E_USER_ERROR:
				case E_RECOVERABLE_ERROR:
					Engine::$LOG->write(
						'('.$errorNumber.'): '.$errorString.' in '.$errorFile.' on line '.$errorLine,
						COUNTRY . '_' . PROJECT . '_errors_' . date('mY')
					);
					exit;
				case E_WARNING:
				case E_CORE_WARNING:
				case E_COMPILE_WARNING:
				case E_USER_WARNING:
					Engine::$LOG->write(
						'('.$errorNumber.'): '.$errorString.' in '.$errorFile.' on line '.$errorLine,
						COUNTRY . '_' . PROJECT . '_warnings_' . date('mY')
					);
					break;
				default:
					Engine::$LOG->write(
						'('.$errorNumber.'): '.$errorString.' in '.$errorFile.' on line '.$errorLine,
						COUNTRY . '_' . PROJECT . '_notices_' . date('dmY')
					);
					break;
			}
		}
	}
    return true;
}


/**
 * @param string $key
 * @return mixed
 */
function conf($key) {
	return Config::get($key);
}


/**
 * @param string $getKey
 * @param string $type
 * @param bool $ignoreStripTags
 * @return array|bool|float|int|null|string
 */
function get($getKey = '', $type = 'any', $ignoreStripTags = false) {
	return Utils::getGet($getKey, $type, $ignoreStripTags);
}


/**
 * @param string $postKey
 * @param string $type
 * @param bool $ignoreStripTags
 * @return array|bool|float|int|null|string
 */
function post($postKey = '', $type = 'any', $ignoreStripTags = false) {
	return Utils::getPost($postKey, $type, $ignoreStripTags);
}


/**
 * @param string $postKey
 * @param string $type
 * @param bool $ignoreStripTags
 * @return array|bool|float|int|null|string
 */
function cookie($cookieKey = '', $type = 'any', $ignoreStripTags = false) {
	return Utils::getCookie($cookieKey, $type, $ignoreStripTags);
}


/**
 * @param $const
 * @param bool $redirect
 * @param string $message
 * @return bool
 */
function perm($const, $redirect = false, $message = '') {
	return Login::hasPermission($const, $redirect, $message);
}